package cn.admin.config.common.protocol;

import java.io.*;

public class Swizzle implements Serializable {

    private byte[] bytes;
    private int serialization;
    private Object object;
    private static final int SERIALIZED_BY_JAVA = 1;
    private static final long serialVersionUID = 1L;

    public Swizzle(Object o) {
        object = o;
    }

    public Swizzle(byte[] bytes) {
        this.bytes = bytes;
        this.serialization = 1;
    }

    public Object extract() throws IOException, ClassNotFoundException {
        if (this.isInBytes()) {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            if (this.serialization != 1) {
                throw new IOException("Unsupported serialization type: " + this.serialization);
            }

            ObjectInputStream input = new ObjectInputStream(bis);
            this.object = input.readObject();
        }
        return this.object;
    }

    public boolean isInBytes() {
        return this.bytes != null;
    }

    public Object getObject() {
        return this.object;
    }

    public Swizzle object2bytes() {
        if (!this.isInBytes()) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream javaos = null;
            try {
                javaos = new ObjectOutputStream(bos);
                javaos.writeObject(this.object);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    assert javaos != null;
                    javaos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            this.bytes = bos.toByteArray();
            this.serialization = -1;
        }
        return this;
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        this.serialization = in.readByte();
        int size = in.readInt();
        this.bytes = new byte[size];
        in.readFully(this.bytes);
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        if (this.isInBytes()) {
            out.writeByte(this.serialization);
            out.writeInt(this.bytes.length);
            out.write(this.bytes);
        } else {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream javaos = new ObjectOutputStream(bos);

            try {
                javaos.writeObject(this.object);
            } finally {
                try {
                    javaos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            out.writeByte(1);
            out.writeInt(bos.size());
            out.write(bos.toByteArray());
        }

    }

}
